package com.jianbing.mongo;

import com.jianbing.util.JianbingConstants;
import com.jianbing.util.PropertiesUtils;
import com.mongodb.*;
import com.mongodb.client.MongoDatabase;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.ArrayList;
import java.util.List;

/**
 * 面向document的mongodb
 * Created by Han, Tixiang on 2016/8/23 0023.
 */
public class MongoConnections {
    private static Log log = LogFactory.getLog(MongoConnections.class);
    private static MongoClient mongoClient = null;

    private static MongoClient createMongoDBClient() {
        // 构建Seed列表
        List<ServerAddress> seedList = new ArrayList<ServerAddress>();
        ServerAddress seed1 = new ServerAddress(PropertiesUtils.getProperties(JianbingConstants.mongoDB_server1), Integer.valueOf(PropertiesUtils.getProperties(JianbingConstants.mongoDB_port1)));
        String username = PropertiesUtils.getProperties(JianbingConstants.mongoDB_username);
        String password = PropertiesUtils.getProperties(JianbingConstants.mongoDB_password);
        String DEFAULT_DB = PropertiesUtils.getProperties(JianbingConstants.mongoDB_DEFAULT_DB);
        String ReplSetName = PropertiesUtils.getProperties(JianbingConstants.mongoDB_ReplSetName);
        seedList.add(seed1);

        // 构建鉴权信息
        List<MongoCredential> credentials = new ArrayList<MongoCredential>();
        credentials.add(MongoCredential.createScramSha1Credential(username,
                DEFAULT_DB, password.toCharArray()));

        // 构建操作选项，requiredReplicaSetName属性外的选项根据自己的实际需求配置，默认参数满足大多数场景
        MongoClientOptions options = MongoClientOptions.builder().requiredReplicaSetName(ReplSetName).socketKeepAlive(true)
                .connectionsPerHost(100).minConnectionsPerHost(10).
                        threadsAllowedToBlockForConnectionMultiplier(1000000).socketTimeout(0).
                        maxWaitTime(1000 * 60 * 200).serverSelectionTimeout(1000 * 60 * 200).connectTimeout(1000 * 60 * 20).
                        maxConnectionIdleTime(0).maxConnectionLifeTime(0).build();
        return new MongoClient(seedList, credentials, options);
    }

    public static MongoClient createMongoDBClientWithURI() {
        //另一种通过URI初始化
        //mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]
        ServerAddress seed1 = new ServerAddress(PropertiesUtils.getProperties(JianbingConstants.mongoDB_server1), Integer.valueOf(PropertiesUtils.getProperties(JianbingConstants.mongoDB_port1)));
        String username = PropertiesUtils.getProperties(JianbingConstants.mongoDB_username);
        String password = PropertiesUtils.getProperties(JianbingConstants.mongoDB_password);
        String DEFAULT_DB = PropertiesUtils.getProperties(JianbingConstants.mongoDB_DEFAULT_DB);
        String ReplSetName = PropertiesUtils.getProperties(JianbingConstants.mongoDB_ReplSetName);
        MongoClientURI connectionString = new MongoClientURI("mongodb://" + username + ":" + password + "@" +
                seed1 + "/" +
                DEFAULT_DB +
                "?replicaSet=" + ReplSetName);
        return new MongoClient(connectionString);
    }

    private static MongoClient initMongoClient() {
        MongoClient mongoClient = null;
        try {
            // 连接到 mongodb 服务
            if (PropertiesUtils.getProperties(JianbingConstants.mongoDB_server1).equals("localhost")) {
                MongoClientOptions options = MongoClientOptions.builder().socketKeepAlive(true)
                        .connectionsPerHost(60).minConnectionsPerHost(10).
                                threadsAllowedToBlockForConnectionMultiplier(1000000).socketTimeout(0).
                                maxWaitTime(1000 * 60 * 200).serverSelectionTimeout(1000 * 60 * 200).connectTimeout(1000 * 60 * 20).
                                maxConnectionIdleTime(0).maxConnectionLifeTime(0).build();
                ServerAddress dbAddress = new ServerAddress(PropertiesUtils.getProperties(JianbingConstants.mongoDB_server1), Integer.valueOf(PropertiesUtils.getProperties(JianbingConstants.mongoDB_port1)));
                mongoClient = new MongoClient(dbAddress, options);   //for local mongodb
            } else {
                mongoClient = createMongoDBClient();

            }
            return mongoClient;
        } catch (Exception e) {
            log.error(e.toString(),e);
        }
        return null;
    }

    public static MongoClient getMongoClient() {
        return mongoClient;
    }


    public static MongoDatabase getDatabase(String databaseName) {
        try {
            if (mongoClient == null) {
                synchronized (MongoConnections.class) {
                    if (mongoClient == null) {
                        mongoClient = initMongoClient();
                    }
                }
            }

            MongoDatabase mongoDatabase = mongoClient.getDatabase(databaseName);
            return mongoDatabase;

        } catch (Exception e) {
            log.error("getDatabase error");
            log.error(e.toString(),e);
        }
        return null;
    }
}
